package org.example.beetlsql.mutiple.conf;

import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.beetl.sql.core.ExecuteContext;
import org.beetl.sql.core.SQLManager;
import org.beetl.sql.core.SQLManagerBuilder;
import org.beetl.sql.core.SqlId;
import org.beetl.sql.ext.DBInitHelper;
import org.beetl.sql.ext.DebugInterceptor;
import org.beetl.sql.ext.spring.SpringConnectionSource;
import org.beetl.sql.starter.SQLManagerCustomize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

import javax.sql.DataSource;
import java.sql.Connection;

/**
 * 一主俩从配置
 */
@Configuration
@Slf4j
public class MutipleDataSourceConfig {
    @Autowired
    ApplicationContext ctx;

    @Bean(name = "master")
    public DataSource datasource(Environment env) {
        HikariDataSource ds = new HikariDataSource();
        ds.setJdbcUrl(env.getProperty("spring.datasource1.url"));
        ds.setUsername(env.getProperty("spring.datasource1.username"));
        ds.setPassword(env.getProperty("spring.datasource1.password"));
        ds.setDriverClassName(env.getProperty("spring.datasource1.driver-class-name"));
        return ds;
    }

	@Bean(name = "slave1")
	public DataSource datasource1(Environment env) {
		HikariDataSource ds = new HikariDataSource();
		ds.setJdbcUrl(env.getProperty("spring.datasource2.url"));
		ds.setUsername(env.getProperty("spring.datasource2.username"));
		ds.setPassword(env.getProperty("spring.datasource2.password"));
		ds.setDriverClassName(env.getProperty("spring.datasource2.driver-class-name"));
		return ds;
	}

	@Bean(name = "slave2")
	public DataSource datasource2(Environment env) {
		HikariDataSource ds = new HikariDataSource();
		ds.setJdbcUrl(env.getProperty("spring.datasource3.url"));
		ds.setUsername(env.getProperty("spring.datasource3.username"));
		ds.setPassword(env.getProperty("spring.datasource3.password"));
		ds.setDriverClassName(env.getProperty("spring.datasource3.driver-class-name"));
		return ds;
	}


    /**
     * 自动初始化所有数据和配置，真实项目不许要
     * @return
     */
    @Bean
    public SQLManagerCustomize mySQLManagerCustomize(){
        return new SQLManagerCustomize(){
            @Override
            public void customize(String sqlMangerName, SQLManager manager) {
            	//初始化sql，这里也可以对sqlManager进行修改
				DBInitHelper.executeSqlScript(manager.getDs().getMasterSource()
						,MutipleDataSourceConfig.class.getResourceAsStream("/db/schema1.sql"));
				DataSource[] slaves = manager.getDs().getSlaves();
				//初始化从数据库
				for(DataSource ds:slaves){
					DBInitHelper.executeSqlScript(ds
							,MutipleDataSourceConfig.class.getResourceAsStream("/db/schema1.sql"));
				}

            }
			//为了监控使用的数据库
			@Override
			public void customizeBuild(String sqlMangerName, SQLManagerBuilder builder){
				SpringConnectionSource ds = (SpringConnectionSource)builder.getDs();
				TrackedSpringConnectionSource trackedSpringConnectionSource = new TrackedSpringConnectionSource(ds.getMasterSource(),ds.getSlaveSource());
				builder.setDs(trackedSpringConnectionSource);
			}
        };
    }

	public static class TrackedSpringConnectionSource extends SpringConnectionSource{
		public TrackedSpringConnectionSource(DataSource master, DataSource[] slaves) {
			super(master, slaves);

		}
		public Connection getConn(ExecuteContext ctx, boolean isUpdate){
			Connection connection = super.getConn(ctx,isUpdate);
			log.info("use connection "+connection);
			return connection;
		}
	}

}
